//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

using System;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.Workflow.ComponentModel;

namespace Microsoft.Research.ScientificWorkflow.Activities
{
    [Name("FTPUpload")]
    [Description("Activity to upload a file to FTP Server.")]
    [WorkflowCategory("Web")]
    public class FTPFileUploadActivity : Activity
    {
        #region Dependency Properties

        public static DependencyProperty FTPRequestObjectProperty = DependencyProperty.Register("FTPRequestObject",
            typeof(FtpWebRequest), typeof(FTPFileUploadActivity));

        [RequiredInputParam]
        [Name("FTP Connection")]
        [Description("Connection Object to the FTP server.")]
        public FtpWebRequest FTPRequestObject
        {
            get
            {
                return ((FtpWebRequest)(base.GetValue(FTPFileUploadActivity.FTPRequestObjectProperty)));
            }
            set
            {
                base.SetValue(FTPFileUploadActivity.FTPRequestObjectProperty, value);
            }
        }

        public static DependencyProperty UploadFileProperty = DependencyProperty.Register("UploadFile",
            typeof(FileInfo), typeof(FTPFileUploadActivity));

        [RequiredInputParam]
        [Name("File")]
        [Description("File to be uploaded to the FTP server.")]
        public FileInfo UploadFile
        {
            get
            {
                return ((FileInfo)(base.GetValue(FTPFileUploadActivity.UploadFileProperty)));
            }
            set
            {
                base.SetValue(FTPFileUploadActivity.UploadFileProperty, value);
            }
        }

        #endregion

        #region Overridden Methods

        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            this.FTPRequestObject.KeepAlive = false;
            this.FTPRequestObject.Method = WebRequestMethods.Ftp.UploadFile;
            this.FTPRequestObject.UseBinary = true;
            this.FTPRequestObject.ContentLength = this.UploadFile.Length;

            // The buffer size is set to 2kb
            int buffLength = 2048;
            byte[] buff = new byte[buffLength];
            int contentLen;

            // Opens a file stream (System.IO.FileStream) to read the file
            // to be uploaded
            FileStream fs = this.UploadFile.OpenRead();

            try
            {
                // Stream to which the file to be upload is written
                Stream strm = this.FTPRequestObject.GetRequestStream();

                // Read from the file stream 2kb at a time
                contentLen = fs.Read(buff, 0, buffLength);

                // Till Stream content ends
                while (contentLen != 0)
                {
                    // Write Content from the file stream to the FTP Upload
                    // Stream
                    strm.Write(buff, 0, contentLen);
                    contentLen = fs.Read(buff, 0, buffLength);
                }

                // Close the file stream and the Request Stream
                strm.Close();
                fs.Close();
            }
            catch (Exception)
            {
                return ActivityExecutionStatus.Faulting;
            }

            return ActivityExecutionStatus.Closed;
        }

        #endregion
    }
}
